< Back
# Simplest look at Reactive.
Code first, see how it works in action. This might help to grasp the concept easier.
Go to https://start.spring.io/ add **Spring Reactive Web** and **Lombok**
## Using annotation way to define controller.
```java
package com.kone.sandbox.reactiverest.controller;
import com.kone.sandbox.reactiverest.dto.Echo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
@RestController
public class EchoController {
@GetMapping("/echo")
public Mono<Echo> echo() {
var resp = Echo.builder().message("echo...").build();
return Mono.just(resp);
}
}
```
Echo dto
```java
package com.kone.sandbox.reactiverest.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Echo {
private String message;
}
```
That is all! Then create The test.
```java
package com.kone.sandbox.reactiverest.controller;
import com.kone.sandbox.reactiverest.dto.Echo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.context.annotation.Import;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@WebFluxTest
@Import({EchoController.class})
class EchoControllerTest {
@Autowired
private WebTestClient client;
@Test
void testEcho() {
client.get().uri("/echo").exchange().expectStatus().isOk().expectBody(Echo.class).value(v -> {
assertThat(v.getMessage()).isEqualTo("echo...");
});
}
}
```
using `curl` to test it manually
```shell
$ curl localhost:8080/echo
{"message":"echo..."}
```
## Using Functional style
Create **Handler**
```java
package com.kone.sandbox.reactiverest.handler;
import com.kone.sandbox.reactiverest.dto.Greeting;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
public class GreetingHandler {
public Mono<ServerResponse> hello(ServerRequest request) {
return ServerResponse
.ok()
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(Greeting.builder().message("Hello, Spring!").build()));
}
}
```
Greeting DTO
```java
package com.kone.sandbox.reactiverest.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Greeting {
private String message;
}
```
add Router
```java
package com.kone.sandbox.reactiverest.router;
import com.kone.sandbox.reactiverest.handler.GreetingHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RequestPredicates.accept;
@Configuration(proxyBeanMethods = false)
public class GreetingRouter {
@Bean
public RouterFunction<ServerResponse> route(GreetingHandler greetingHandler) {
return RouterFunctions
.route(GET("/hello").and(accept(MediaType.APPLICATION_JSON)), greetingHandler::hello);
}
}
```
Test it
```java
package com.kone.sandbox.reactiverest.router;
import com.kone.sandbox.reactiverest.dto.Greeting;
import com.kone.sandbox.reactiverest.handler.GreetingHandler;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.WebFluxTest;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@WebFluxTest
@Import({GreetingRouter.class, GreetingHandler.class})
class GreetingRouterTest {
@Autowired
private WebTestClient webTestClient;
@Test
void testHello() {
webTestClient.get().uri("/hello")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.expectStatus().isOk()
.expectBody(Greeting.class).value(
g -> {
assertThat(g.getMessage()).isEqualTo("Hello, Spring!");
});
}
}
```
use `curl` manually
```shell
$ curl localhost:8080/hello
{"message":"Hello, Spring!"}
```